#include <iostream>
#include <string>
#include <memory>

using namespace std;

//抽象产品类
class Computer{
public:
    Computer(){

    }

    void setBoard(const string& board){
        _board = board;
    }

    void setDisplay(const string& display){
        _display = display;
    }

    virtual void setOS() = 0;

    void show(){
        cout << "board:" << _board << " display:" << _display << " OS:" << _OS << endl;
    }

protected:
    string _board;
    string _display;
    string _OS;
};

class MacBook : public Computer{
public:
    void setOS() override{
        _OS = "MacOS";
    }

private:

};

//抽象建造者类
class Builder{
public:
    virtual void buildBoard(const string &board) = 0;
    virtual void buildDisplay(const string &display) = 0;
    virtual void buildOS() = 0;
    virtual shared_ptr<Computer> build() = 0;
};

//具体建造者
class MacBookBuilder : public Builder{
public:

    //_computer管理一个MacBook对象
    MacBookBuilder():_computer(new MacBook()){
        
    }

    void buildBoard(const string& board) override{
        _computer->setBoard(board);
    }

    void buildDisplay(const string &display) override{
        _computer->setDisplay(display);
    }
    
    void buildOS(){
        _computer->setOS();
    }

    shared_ptr<Computer> build(){
        return _computer;
    }

private:
    shared_ptr<Computer> _computer;
};


//指挥者类
class Director{
public:
    //根据传入的具体建造者创建相应的产品
    Director(Builder *builder):_builder(builder){

    }

    void construct(const string& board, const string& display){
        _builder->buildBoard(board);
        _builder->buildDisplay(display);
        _builder->buildOS();

    }

private:
    shared_ptr<Builder> _builder;
};

int main(){
    //建造者
    Builder *builder = new MacBookBuilder();
    //指挥者管理建造者
    unique_ptr<Director> director(new Director(builder));
    //指挥者让具体建造者生产指定部件
    //具体建造者进行生产
    director->construct("apple", "XDR");
    //获取生产出来的产品
    shared_ptr<Computer> computer = builder->build();
    computer->show();
    return 0;
}